﻿using Sunny.UI;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace CoreShop.App
{
    [ToolboxItem(true)]
    [DefaultEvent("ValueChanged")]
    public class UIHandInputTextBox : UIDropControl, IToolTip, IHideDropDown
    {
        public UIHandInputTextBox()
        {
            InitializeComponent();
            edit.KeyDown += Edit_KeyDown;
            edit.Leave += Edit_Leave;
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            HideHandInput();
        }

        public Control ExToolTipControl()
        {
            return edit;
        }

        private void Edit_Leave(object sender, EventArgs e)
        {
            HideDropDown();
            HideHandInput();
        }

        private readonly UIHandInputItem numPad = new UIHandInputItem();
        private UISymbolButton btnShowHand;
        private UIDropDown numPadForm;

        public void HideDropDown()
        {
            try
            {
                if (NumPadForm != null && NumPadForm.Visible)
                    NumPadForm.Close();
            }
            catch
            {
            }
        }

        private UIDropDown NumPadForm
        {
            get
            {
                if (numPadForm == null)
                {
                    numPadForm = new UIDropDown(numPad);

                    if (numPadForm != null)
                    {
                        numPadForm.VisibleChanged += NumBoardForm_VisibleChanged;
                        numPadForm.ValueChanged += NumBoardForm_ValueChanged;
                    }
                }

                return numPadForm;
            }
        }

        public const int WM_CHAR = 256;
        private void NumBoardForm_ValueChanged(object sender, object value)
        {
            int start = edit.SelectionStart;
            switch ((int)value)
            {
                default:
                    Sunny.UI.Win32.User.PostMessage(edit.Handle, WM_CHAR, (int)value, 0);
                    edit.SelectionStart = start;
                    edit.Select(start, 0);
                    edit.Focus();
                    break;
            }
        }

        private void NumBoardForm_VisibleChanged(object sender, System.EventArgs e)
        {
            dropSymbol = SymbolNormal;
            if (NumPadForm.Visible)
            {
                dropSymbol = SymbolDropDown;
                numPad.SetButtons();
            }

            Invalidate();
        }

        private int symbolSize = 24;
        public int SymbolSize
        {
            get => symbolSize;
            set
            {
                symbolSize = value;
                Invalidate();
            }
        }

        public void ShowDropDown()
        {
            NumPadForm.AutoClose = false;
            NumPadForm.Size = new Size(504, 361);
            numPad.SetDPIScale();
            numPad.SetStyleColor(UIStyles.ActiveStyleColor);

            if (!NumPadForm.Visible)
            {
                ShowHandInput();
                if (m_HandPWin == null) return;
                if (m_HandAppWin == IntPtr.Zero) return;

                Point screenCoords = this.PointToScreen(new Point(0, 0));
                Screen screen = Screen.FromPoint(MousePosition);
                if (screenCoords.Y + Height + 361 > screen.WorkingArea.Height)
                {
                    NumPadForm.Show(this, 0, -362);
                }
                else
                {
                    NumPadForm.Show(this, 0, Height);
                }
            }

            edit.Focus();
        }

        protected override void OnPaintFore(Graphics g, GraphicsPath path)
        {
            g.FillRectangle(GetFillColor(), new Rectangle(Width - Padding.Right, 2, Padding.Right - 1, Height - 4));
            Color color = GetRectColor();
            g.DrawFontImage(dropSymbol, SymbolSize, color, new Rectangle(Width - Padding.Right, 0, Padding.Right, Height), 1, 0);
        }

        private void Edit_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
            {
                if (!NumPadForm.Visible)
                    ShowDropDown();
            }
            else if (e.KeyCode == Keys.Escape)
            {
                NumPadForm.Close();
            }
            else if (e.KeyCode == Keys.Return)
            {
                if (NumPadForm.Visible)
                {
                    NumPadForm.Close();
                }
                else
                {
                    ShowDropDown();
                }
            }
            else
            {
                base.OnKeyDown(e);
            }
        }

        string m_HandExeName = DirEx.CurrentDir() + "HandInput\\handinput.exe";
        /// <summary>
        /// The m hand application win
        /// </summary>
        IntPtr m_HandAppWin;
        /// <summary>
        /// The m hand p win
        /// </summary>
        Process m_HandPWin = null;

        private void HideHandInput()
        {
            if (m_HandAppWin != IntPtr.Zero)
            {
                if (m_HandPWin != null && !m_HandPWin.HasExited)
                    m_HandPWin.Kill();
                m_HandPWin = null;
                m_HandAppWin = IntPtr.Zero;
            }
        }

        public void KillHandInput()
        {
            var lstP = Process.GetProcessesByName("handinput");
            if (lstP.Length > 0)
            {
                foreach (var item in lstP)
                {
                    try { item.Kill(); } catch { }
                }
            }
        }

        private void ShowHandInput()
        {
            //var lstP = Process.GetProcessesByName("handinput");
            //if (lstP.Length > 0)
            //{
            //    foreach (var item in lstP)
            //    {
            //        item.Kill();
            //    }
            //}
            //m_HandAppWin = IntPtr.Zero;

            if (m_HandPWin == null)
            {
                m_HandPWin = null;

                m_HandPWin = System.Diagnostics.Process.Start(this.m_HandExeName);
                m_HandPWin.WaitForInputIdle();
            }

            while (m_HandPWin.MainWindowHandle == IntPtr.Zero)
            {
                Thread.Sleep(10);
            }

            m_HandAppWin = m_HandPWin.MainWindowHandle;
            SetParent(m_HandAppWin, numPad.Handle);
            SetForegroundWindow(this.FindForm().Handle);
            MoveWindow(m_HandAppWin, -111, -41, 626, 412, true);
        }

        /// <summary>
        /// Sets the parent.
        /// </summary>
        /// <param name="hWndChild">The h WND child.</param>
        /// <param name="hWndNewParent">The h WND new parent.</param>
        /// <returns>System.Int64.</returns>
        [DllImport("user32.dll", SetLastError = true)]
        private static extern long SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        /// <summary>
        /// Sets the foreground window.
        /// </summary>
        /// <param name="hWnd">The h WND.</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>
        /// Moves the window.
        /// </summary>
        /// <param name="hwnd">The HWND.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="cx">The cx.</param>
        /// <param name="cy">The cy.</param>
        /// <param name="repaint">if set to <c>true</c> [repaint].</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

        private void InitializeComponent()
        {
            this.btnShowHand = new Sunny.UI.UISymbolButton();
            this.SuspendLayout();
            // 
            // edit
            // 
            this.edit.Location = new System.Drawing.Point(4, 12);
            this.edit.Size = new System.Drawing.Size(133, 19);
            // 
            // btnShowHand
            // 
            this.btnShowHand.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this.btnShowHand.BackColor = System.Drawing.Color.White;
            this.btnShowHand.Cursor = System.Windows.Forms.Cursors.Hand;
            this.btnShowHand.FillColor = System.Drawing.Color.White;
            this.btnShowHand.FillColor2 = System.Drawing.Color.White;
            this.btnShowHand.FillHoverColor = System.Drawing.Color.White;
            this.btnShowHand.FillPressColor = System.Drawing.Color.White;
            this.btnShowHand.FillSelectedColor = System.Drawing.Color.White;
            this.btnShowHand.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.btnShowHand.ForeColor = System.Drawing.Color.Black;
            this.btnShowHand.Location = new System.Drawing.Point(124, 3);
            this.btnShowHand.MinimumSize = new System.Drawing.Size(1, 1);
            this.btnShowHand.Name = "btnShowHand";
            this.btnShowHand.Radius = 15;
            this.btnShowHand.RadiusSides = Sunny.UI.UICornerRadiusSides.None;
            this.btnShowHand.RectColor = System.Drawing.Color.LightGray;
            this.btnShowHand.RectHoverColor = System.Drawing.Color.White;
            this.btnShowHand.RectPressColor = System.Drawing.Color.White;
            this.btnShowHand.RectSelectedColor = System.Drawing.Color.White;
            this.btnShowHand.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
            this.btnShowHand.Size = new System.Drawing.Size(39, 38);
            this.btnShowHand.Style = Sunny.UI.UIStyle.Custom;
            this.btnShowHand.StyleCustomMode = true;
            this.btnShowHand.Symbol = 61508;
            this.btnShowHand.SymbolColor = System.Drawing.Color.DodgerBlue;
            this.btnShowHand.SymbolHoverColor = System.Drawing.Color.DeepSkyBlue;
            this.btnShowHand.SymbolPressColor = System.Drawing.Color.DodgerBlue;
            this.btnShowHand.SymbolSelectedColor = System.Drawing.Color.DodgerBlue;
            this.btnShowHand.TabIndex = 204;
            this.btnShowHand.Tag = "1";
            this.btnShowHand.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.btnShowHand.Click += new System.EventHandler(this.btnShowHand_Click);
            // 
            // UIHandInputTextBox
            // 
            this.Controls.Add(this.btnShowHand);
            this.Name = "UIHandInputTextBox";
            this.Size = new System.Drawing.Size(167, 44);
            this.SymbolDropDown = 0;
            this.SymbolNormal = 0;
            this.ButtonClick += new System.EventHandler(this.UIHandInputTextBox_ButtonClick);
            this.Controls.SetChildIndex(this.edit, 0);
            this.Controls.SetChildIndex(this.btnShowHand, 0);
            this.ResumeLayout(false);

        }

        protected override void OnClick(EventArgs e)
        {
            //if (MousePosition.X > base.Width - Padding.Right)
            //{
            //    if (NumPadForm.Visible)
            //    {
            //        NumPadForm.Close();
            //    }
            //    else
            //    {
            //        ShowDropDown();
            //    }
            //}
        }

        private void UIHandInputTextBox_ButtonClick(object sender, EventArgs e)
        {

        }

        private void btnShowHand_Click(object sender, EventArgs e)
        {
            if (MousePosition.X > base.Width - Padding.Right)
            {
                if (NumPadForm.Visible)
                {
                    NumPadForm.Close();
                }
                else
                {
                    ShowDropDown();
                }
            }
        }
    }
}
